package com.imesne.office.excel.write;

import com.imesne.office.excel.exception.OfficeException;
import com.imesne.office.excel.model.ExcelCell;
import com.imesne.office.excel.model.ExcelRow;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Collection;
import java.util.List;

/**
 * Created by liyd on 17/7/6.
 */
public class ExcelSaxWriter {


    /**
     * 写excel
     *
     * @param file
     * @param excelSaxWriteHandler
     */
    public void writer(File file, ExcelSaxWriteHandler excelSaxWriteHandler) {

        SXSSFWorkbook wb = null;
        FileOutputStream out = null;
        try {
            wb = new SXSSFWorkbook();
            Sheet sheet = wb.createSheet();

            int totalRowCount = 1;
            int sheetNum = 1;
            int sheetRowNum = 1;
            int loopCount = 1;

            if (this.writeTitleRow(sheet, sheetNum, excelSaxWriteHandler)) {
                totalRowCount++;
                sheetRowNum++;
            }

            List<ExcelRow> excelRows = excelSaxWriteHandler.getRows(loopCount, totalRowCount, sheetRowNum);
            while (excelRows != null && !excelRows.isEmpty()) {

                for (ExcelRow excelRow : excelRows) {

                    if (excelRow.getRowNum() != null) {
                        sheetRowNum = excelRow.getRowNum();
                    }

                    boolean newSheet = excelSaxWriteHandler.isNewSheet(totalRowCount, sheetRowNum);
                    if (newSheet) {
                        sheet = wb.createSheet();
                        sheetNum++;
                        sheetRowNum = 1;
                        if (this.writeTitleRow(sheet, sheetNum, excelSaxWriteHandler)) {
                            totalRowCount++;
                            sheetRowNum++;
                        }
                    }
                    Row row = sheet.createRow(sheetRowNum - 1);
                    this.writeRow(row, excelRow);
                    totalRowCount++;
                    sheetRowNum++;
                }
                loopCount++;
                excelRows = excelSaxWriteHandler.getRows(loopCount, totalRowCount, sheetRowNum);
            }
            out = new FileOutputStream(file);
            wb.write(out);
        } catch (Exception ex) {
            throw new OfficeException("写入excel文件失败", ex);
        } finally {
            IOUtils.closeQuietly(out);
            // 删除临时文件
            if (wb != null) {
                wb.dispose();
                IOUtils.closeQuietly(wb);
            }
        }
    }

    private void writeRow(Row row, ExcelRow excelRow) {
        Collection<ExcelCell> excelCells = excelRow.getExcelCells();
        for (ExcelCell excelCell : excelCells) {
            if (excelCell.getCellNum() == null) {
                throw new OfficeException("cellNum不能为空");
            }
            Cell cell = row.createCell(excelCell.getCellNum());
            cell.setCellValue(excelCell.getValue().toString());
        }
    }

    private boolean writeTitleRow(Sheet sheet, int sheetNum, ExcelSaxWriteHandler excelSaxWriteHandler) {
        ExcelRow titleRows = excelSaxWriteHandler.getTitleRows(sheetNum);
        if (titleRows == null) {
            return false;
        }
        Row row = sheet.createRow(0);
        this.writeRow(row, titleRows);
        return true;
    }
}
